#include <iostream>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "server_socket.h"
#include "common_gestor_envios.h"
#define PENDIENTES 10 	// Cuántas conexiones pendientes se mantienen en cola
#define SHUTDOWN 2

using std::cerr;
using std::endl;
using std::string;

Server_socket::Server_socket(int port){
	fd = socket(AF_INET, SOCK_STREAM, 0);
	addr.sin_family = AF_INET;		// Ordenación de bytes de la máquina
	addr.sin_port = htons(port); 		// Ordenación de bytes de la red
	addr.sin_addr.s_addr = INADDR_ANY;// Rellenar con mi dirección IP
	memset(&(addr.sin_zero), '\0', 8);// Poner a cero el resto
	if (fd == -1){
		cerr<<"server socket constructor"<<endl;
	}
	int num = 1;
	if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&num,sizeof(int)) == -1){ 
		cerr<<"server socket setsockopt"<<endl; 
	} 
}

Server_socket::Server_socket(){
}

Server_socket::~Server_socket(){
}

int Server_socket::get_fd(){
	return fd;
}

struct sockaddr_in Server_socket::get_addr(){
	return addr;
}	
	

int Server_socket::escuchar_puerto(){	
	if (bind(fd, (const struct sockaddr*)&addr,sizeof(struct sockaddr))  == -1){
		cerr<<"server socket bind"<<endl;
		return -1;
	}
	if (listen(fd, PENDIENTES) == -1) {
		cerr<<"server socket listen"<<endl;
		return -1;
	}
	return 0;
}	

int Server_socket::aceptar_conexion(Server_socket* nuevo){
	socklen_t size = sizeof(struct sockaddr_in);
	if ((nuevo->fd = accept(fd, (struct sockaddr*)&(nuevo->addr), &size))
																	== -1){
		cerr<<"accept"<<endl;
		return -1;
	}
	return 0;
}	

int Server_socket::enviar(int aux_fd, string buffer, int tam){
	return gestor->enviar(aux_fd, buffer, tam);
}	

int Server_socket::recibir(int aux_fd, string* buffer, int tam){
	return gestor->recibir(aux_fd, buffer, tam);
}	

void Server_socket::cerrar_comunicacion(){
	if (shutdown(fd, SHUTDOWN) == -1){
		cerr<<"shutdown"<<endl;
	}
}	

void Server_socket::cerrar(){
	close(fd);
}	
